//-------------------------------------------------------------------------------
//Vertex and pixel shader demonstrating ambient and diffuse lighting
// Ambient intensity values are pre baked
//------------------------------------------------------------------------------------------------------

//------------------------------------------------------------------------------------------------------
// Global params provided by the app
//------------------------------------------------------------------------------------------------------
float4x4 g_mWorld;
float4x4 g_mWorldViewProjection;
float4 g_MaterialAmbientColor;
float4 g_MaterialDiffuseColor;
float3 g_LightDir;
float4 g_LightDiffuse;
float4 g_LightAmbient = float4(1, 1, 1, 1);
float g_Alpha = 1;

sampler TextureSampler =
sampler_state {
    MinFilter = Anisotropic;
    MagFilter = LINEAR;
    MipFilter = LINEAR;
    AddressU = WRAP;
    AddressV = WRAP;
};

//---------------------------------------------------------------------------------------------------------------------------
// Input channel (vertex shader)
//---------------------------------------------------------------------------------------------------------------------------
struct InputVS {
float3 Position :
    POSITION;
float3 Normal :
    NORMAL;
float2 TextureUV :
    TEXCOORD;
};

//---------------------------------------------------------------------------------------------------------------------------
// Output channel (vertex shader)
//---------------------------------------------------------------------------------------------------------------------------
struct OutputVS {
float4 Position :
    POSITION;
float3 Normal:
    TEXCOORD0;
float2 TextureUV:
    TEXCOORD1;
};

//---------------------------------------------------------------------------------------------------------------------------
// Vertex shader
//---------------------------------------------------------------------------------------------------------------------------
OutputVS ParticleShaderVS(InputVS input) {
    //Zero out our output
    OutputVS outVS = (OutputVS)0;

    //Transform to homogeneous clipspace
    outVS.Position = mul(float4(input.Position, 1.0f), g_mWorldViewProjection);
    //normals
    outVS.Normal = mul(input.Normal, g_mWorld).xyz;
    outVS.TextureUV = input.TextureUV;

    //return output
    return outVS;
}

//---------------------------------------------------------------------------------------------------------------------------
// Input channel pixel shader
//---------------------------------------------------------------------------------------------------------------------------
struct InputPS {
float3 Normal:
    TEXCOORD0;
float2 TextureUV :
    TEXCOORD1;
};

//---------------------------------------------------------------------------------------------------------------------------
// Pixel shader (input channel):output channel
//---------------------------------------------------------------------------------------------------------------------------
float4 ParticleShaderPS(InputPS input): COLOR {
    //transform light vector into viewspace and normalize
    float4 finalColour = 0;

    float3 L = normalize(g_LightDir);

    //Calculate diff, specular and ambient components of lighht
    float diff = max(0, dot(input.Normal, L));

    finalColour += g_MaterialAmbientColor * g_LightAmbient +
                   g_MaterialDiffuseColor * diff;
    finalColour += g_MaterialDiffuseColor.a;

    finalColour *= tex2D(TextureSampler, input.TextureUV) * 2;

    return float4(finalColour.rgb, finalColour.a * g_Alpha);
}

technique Particle_Shader {
    pass P0
    {
        Lighting = TRUE;
        SpecularEnable = TRUE;
        FillMode = Solid;
        vertexShader = compile vs_3_0 ParticleShaderVS();
        pixelShader = compile ps_3_0 ParticleShaderPS();
    }
}

technique Particle_Shader_Normal_Alpha {
    pass P0
    {
        Lighting = TRUE;
        SpecularEnable = TRUE;
        FillMode = Solid;
        ZEnable = true;
        ZWriteEnable = true;
        ZFunc = LessEqual;
        AlphaBlendEnable = true;
        SrcBlend = SrcAlpha;
        DestBlend = InvSrcAlpha;
        BlendOp = Add;
        vertexShader = compile vs_3_0 ParticleShaderVS();
        pixelShader = compile ps_3_0 ParticleShaderPS();
    }
}